home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Appearance SDK 1.0.4 / Appearance Sample Code / Source / MenuDrawing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-16  |  9.0 KB  |  313 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MenuDrawing.c
  3.  
  4.     Contains:    Code to demonstrate menu drawing routines of the Appearance Manager.
  5.  
  6.     Version:    Appearance 1.0 SDK
  7.  
  8.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                Edward Voas
  13.  
  14.         Other Contact:        7 of 9, Borg Collective
  15.  
  16.         Technology:            OS Technologies Group
  17.  
  18.     Writers:
  19.  
  20.         (edv)    Ed Voas
  21.  
  22.     Change History (most recent first):
  23.  
  24.          <3>     10/1/97    edv        Update to API changes for drawing menu titles and items.
  25.          <2>     9/11/97    edv        Fix DrawMenuTitle.
  26.          <1>     9/11/97    edv        First checked in.
  27. */
  28.  
  29. #include <MacWindows.h>
  30. #include <Appearance.h>
  31.  
  32. void    DrawMenuStuff();
  33. static pascal void    DrawMenuTitle( const Rect* bounds, SInt16 depth, Boolean colorDevice, long userData );
  34. static void    DrawPhonyMenu();
  35.  
  36. static WindowPtr     gMenuWindow = nil;
  37. static Str255        gMenuItems[] =
  38.                     {
  39.                         "\pFirst Item",
  40.                         "\pSecond Item",
  41.                         "\pThird Item",
  42.                         "\p-",
  43.                         "\pFourth Item",
  44.                         "\pFifth Item"
  45.                     };
  46. static ThemeMenuItemType    gMenuItemTypes[] =
  47.                     {
  48.                         kThemeMenuItemScrollUpArrow,
  49.                         kThemeMenuItemHierarchical,
  50.                         kThemeMenuItemPlain,
  51.                         kThemeMenuItemPlain,
  52.                         kThemeMenuItemPlain,
  53.                         kThemeMenuItemScrollDownArrow
  54.                     };
  55.  
  56. #if GENERATINGCFM
  57. RoutineDescriptor sDrawMenuTitleProc = BUILD_ROUTINE_DESCRIPTOR( uppMenuTitleDrawingProcInfo, DrawMenuTitle );
  58. #define DrawMenuTitleProc_()        &sDrawMenuTitleProc
  59. #else
  60. #define DrawMenuTitleProc_()        DrawMenuTitle
  61. #endif
  62.  
  63. //—————————————————————————————————————————————————————————————————————————————————————————
  64. //    • DrawMenuStuff
  65. //—————————————————————————————————————————————————————————————————————————————————————————
  66. //    Draws the menu bar, menu background, etc. for the current theme.
  67. //
  68. void
  69. DrawMenuStuff()
  70. {
  71.     Rect            bounds, menuBarRect;
  72.     DELAY_LONG        junk;
  73.     Rect            tempRect;
  74.     SInt16            height, widthExtra;
  75.     OSErr            err;
  76.     
  77.     if ( gMenuWindow == nil )
  78.     {
  79.         gMenuWindow = GetNewCWindow( 200, nil, (WindowPtr)-1L );
  80.         if ( gMenuWindow == nil ) return;
  81.     }
  82.  
  83.     SetPort( gMenuWindow );
  84.     EraseRect( &gMenuWindow->portRect );
  85.     
  86.     TextFont( 0 );
  87.     TextSize( 0 );
  88.     
  89.     bounds = gMenuWindow->portRect;
  90.     InsetRect( &bounds, 60, 60 );
  91.  
  92.     GetThemeMenuBarHeight( &height );
  93.  
  94.     menuBarRect = bounds;
  95.     menuBarRect.bottom = menuBarRect.top + height;
  96.     
  97.         // Draw a blank normal menu bar
  98.         
  99.     DrawThemeMenuBarBackground( &menuBarRect, kThemeMenuBarNormal, 0 );
  100.     Delay( 60, &junk );
  101.  
  102.         // Draw a blank hilited menu bar
  103.         
  104.     DrawThemeMenuBarBackground( &menuBarRect, kThemeMenuBarSelected, 0 );
  105.     Delay( 60, &junk );
  106.  
  107.         // Draw a menu bar with one menu title
  108.         
  109.     DrawThemeMenuBarBackground( &menuBarRect, kThemeMenuBarNormal, 0 );
  110.     
  111.     GetThemeMenuTitleExtra( &widthExtra, false );
  112.     tempRect = menuBarRect;
  113.     tempRect.left += 10;
  114.     tempRect.right = tempRect.left + widthExtra + StringWidth( "\pFile" );
  115.     DrawThemeMenuTitle( &menuBarRect, &tempRect, kThemeMenuActive, 0, DrawMenuTitleProc_(), (long)"\pFile" );
  116.     Delay( 60, &junk );
  117.  
  118.         // Draw a menu bar with one selected title
  119.         
  120.     DrawThemeMenuBarBackground( &menuBarRect, kThemeMenuBarNormal, 0 );
  121.     tempRect = menuBarRect;
  122.     tempRect.left += 10;
  123.     tempRect.right = tempRect.left + widthExtra + StringWidth( "\pFile" );
  124.     err = DrawThemeMenuTitle( &menuBarRect, &tempRect, kThemeMenuSelected, 0, DrawMenuTitleProc_(), (long)"\pFile" );
  125.     Delay( 60, &junk );
  126.  
  127.         // Draw a menu bar with one disabled title
  128.         
  129.     DrawThemeMenuBarBackground( &menuBarRect, kThemeMenuBarNormal, 0 );
  130.     tempRect = menuBarRect;
  131.     tempRect.left += 10;
  132.     tempRect.right = tempRect.left + widthExtra + StringWidth( "\pFile" );
  133.     err = DrawThemeMenuTitle( &menuBarRect, &tempRect, kThemeMenuDisabled, 0, DrawMenuTitleProc_(), (long)"\pFile" );
  134.     Delay( 60, &junk );
  135.  
  136.     EraseRect( &gMenuWindow->portRect );
  137.     tempRect = bounds;
  138.     DrawThemeMenuBackground( &tempRect, kThemeMenuTypePullDown );
  139.     Delay( 60, &junk );
  140.  
  141.     EraseRect( &gMenuWindow->portRect );
  142.     tempRect = bounds;
  143.     DrawThemeMenuBackground( &tempRect, kThemeMenuTypePopUp );
  144.     Delay( 60, &junk );
  145.  
  146.     EraseRect( &gMenuWindow->portRect );
  147.     tempRect = bounds;
  148.     DrawThemeMenuSeparator( &tempRect );
  149.     
  150.  
  151.     SInt16 theHeight, theWidth;
  152.     GetThemeMenuSeparatorHeight( &theHeight );    
  153.     GetThemeMenuItemExtra( kThemeMenuItemPlain, &theHeight, &theWidth );
  154.  
  155.     Delay( 60, &junk );
  156.  
  157.     Rect    temp2;
  158.     
  159.     EraseRect( &gMenuWindow->portRect );
  160.     tempRect = bounds;
  161.     temp2 = tempRect;
  162. //    InsetRect( &temp2, 0, 20 );
  163.     DrawThemeMenuItem( &temp2, &tempRect, temp2.top, temp2.bottom, kThemeMenuActive, kThemeMenuItemPlain, nil, 0 );
  164.     Delay( 60, &junk );
  165.     DrawThemeMenuItem( &temp2, &tempRect, temp2.top, temp2.bottom, kThemeMenuSelected, kThemeMenuItemPlain, nil, 0 );
  166.     Delay( 60, &junk );
  167.     
  168.     EraseRect( &gMenuWindow->portRect );
  169.     DrawPhonyMenu();
  170. }
  171.  
  172. //—————————————————————————————————————————————————————————————————————————————————————————
  173. //    • DrawMenuTitle
  174. //—————————————————————————————————————————————————————————————————————————————————————————
  175. //    Draws the menu title centered in the rectangle passed.
  176. //
  177. static pascal void
  178. DrawMenuTitle( const Rect* bounds, SInt16 depth, Boolean colorDevice, long userData )
  179. {
  180.     #pragma unused( depth, colorDevice )
  181.     
  182.     short            height, space, h, v;
  183.     short            charHeight;
  184.     FontInfo        fontInfo;
  185.     StringPtr        string = (StringPtr)userData;
  186.     
  187.     height = bounds->bottom - bounds->top;
  188.     space = bounds->right - bounds->left;
  189.     
  190.     GetFontInfo( &fontInfo );
  191.     
  192.     h = bounds->left;
  193.     charHeight = fontInfo.ascent + fontInfo.descent;
  194.     v = ( height - charHeight ) / 2 + bounds->top + fontInfo.ascent;
  195.     MoveTo( h, v );
  196.  
  197.     DrawString( string );
  198. }
  199.  
  200. //—————————————————————————————————————————————————————————————————————————————————————————
  201. //    • DrawPhonyMenu
  202. //—————————————————————————————————————————————————————————————————————————————————————————
  203. //    Draws a menu complete with items. It uses the Appearance Manager routines to calculate
  204. //    the item width and height and also iterates over each item, hiliting and unhiliting it.
  205. //
  206. static void
  207. DrawPhonyMenu()
  208. {
  209.     Rect        menuRect, itemRect;
  210.     SInt16        height, width, temp;
  211.     SInt16        i, itemHeight;
  212.     SInt16        extraHeight, extraWidth, sepHeight, maxExtraWidth;
  213.     FontInfo    fontInfo;
  214.     DELAY_LONG    junk;
  215.     
  216.         // Calculate the width and height of our menu.
  217.     
  218.     GetFontInfo( &fontInfo );
  219.     GetThemeMenuSeparatorHeight( &sepHeight );
  220.     
  221.     height = 0;
  222.     width = 0;
  223.     maxExtraWidth = 0;
  224.     
  225.     itemHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
  226.     
  227.     for ( i = 1; i <= 6; i++ )
  228.     {
  229.         if ( gMenuItems[ i - 1 ][1] != '-' )
  230.         {
  231.                 // Depending on the type of menu item background you're going
  232.                 // to draw, the width may differ. We must make sure we've use the biggest
  233.                 // extraWidth we get, so call GetThemeMenuItemExtra each time thru.
  234.                 
  235.             GetThemeMenuItemExtra( gMenuItemTypes[ i-1 ],  &extraHeight, &extraWidth );
  236.  
  237.             temp = StringWidth( gMenuItems[ i - 1 ] );
  238.             if ( temp > width )
  239.                 width = temp;
  240.             
  241.             if ( extraWidth > maxExtraWidth )
  242.                 maxExtraWidth = extraWidth;
  243.             
  244.             height += (itemHeight + extraHeight);
  245.         }
  246.         else
  247.             height += sepHeight;
  248.     }
  249.     
  250.     width += maxExtraWidth;
  251.     
  252.         // OK, now that we've gotten our height and width, lets draw the menu
  253.         // background for fun.
  254.         
  255.     menuRect.top = 10;
  256.     menuRect.left = 10;
  257.     menuRect.bottom = menuRect.top + height;
  258.     menuRect.right = menuRect.left + width;
  259.     
  260.     DrawThemeMenuBackground( &menuRect, kThemeMenuTypePullDown );
  261.     
  262.         // Now let's draw each item, using the calculations made above. Here
  263.         // we assume that the itemHeights are all the same, but we could have
  264.         // stored the heights and used each individual item's height.
  265.         
  266.     itemRect = menuRect;
  267.     itemRect.bottom = itemRect.top;
  268.     
  269.     for ( i = 1; i <= 6; i++ )
  270.     {
  271.         if ( gMenuItems[ i - 1 ][1] != '-' )
  272.         {
  273.             itemRect.bottom = itemRect.top + itemHeight + extraHeight;
  274.             DrawThemeMenuItem( &menuRect, &itemRect, menuRect.top, menuRect.bottom, kThemeMenuActive, gMenuItemTypes[ i-1 ], DrawMenuTitleProc_(),  (long)&gMenuItems[ i - 1] );
  275.         }
  276.         else
  277.         {
  278.             itemRect.bottom = itemRect.top + sepHeight;
  279.             DrawThemeMenuSeparator( &itemRect );
  280.         }
  281.         itemRect.top = itemRect.bottom;
  282.     }
  283.     Delay( 60, &junk );
  284.     
  285.         // Swell, now let's step thru each item, drawing it in the selected, active,
  286.         // disabled, and then in the active state again.
  287.         
  288.     itemRect = menuRect;
  289.     itemRect.bottom = itemRect.top;
  290.     
  291.     for ( i = 1; i <= 6; i++ )
  292.     {
  293.         if ( gMenuItems[ i - 1 ][1] != '-' )
  294.         {
  295.             itemRect.bottom = itemRect.top + itemHeight + extraHeight;
  296.             DrawThemeMenuItem( &menuRect, &itemRect, menuRect.top, menuRect.bottom, kThemeMenuSelected, gMenuItemTypes[ i-1 ], DrawMenuTitleProc_(),  (long)&gMenuItems[ i - 1] );
  297.             Delay( 30, &junk );
  298.             DrawThemeMenuItem( &menuRect, &itemRect, menuRect.top, menuRect.bottom, kThemeMenuActive, gMenuItemTypes[ i-1 ], DrawMenuTitleProc_(),  (long)&gMenuItems[ i - 1] );
  299.             Delay( 30, &junk );
  300.             DrawThemeMenuItem( &menuRect, &itemRect, menuRect.top, menuRect.bottom, kThemeMenuDisabled, gMenuItemTypes[ i-1 ], DrawMenuTitleProc_(),  (long)&gMenuItems[ i - 1] );
  301.             Delay( 30, &junk );
  302.             DrawThemeMenuItem( &menuRect, &itemRect, menuRect.top, menuRect.bottom, kThemeMenuActive, gMenuItemTypes[ i-1 ], DrawMenuTitleProc_(),  (long)&gMenuItems[ i - 1] );
  303.             Delay( 30, &junk );
  304.         }
  305.         else
  306.         {
  307.             itemRect.bottom = itemRect.top + sepHeight;
  308.             DrawThemeMenuSeparator( &itemRect );
  309.         }
  310.         itemRect.top = itemRect.bottom;
  311.     }
  312. }
  313.